﻿using UnityEngine;
using System;

namespace xres
{


    public class ManifestLoader : BaseLoader
    {
        public const string Err_Load_Bundle = "Err_Load_Bundle";
        public const string Err_Load_Asset = "Err_Load_Asset";

        /// <summary>
        /// bundle名字. test1/test1_1/a.u3d这种路径方式的名字, bundle包也会用文件夹的方式存放
        /// </summary>
        readonly string _bundleName;

        AsyncOperation _op;

        public AssetBundle bundle { get; internal set; }

        /// <summary>
        /// 最终加载到的资源
        /// </summary>
        public AssetBundleManifest manifest { get; internal set; }


        public ManifestLoader(string bundleName)
        {
            _bundleName = bundleName;
        }

        public float CheckProgress()
        {
            switch (_state)
            {
            case LoaderState.Init:
                return 0;

            case LoaderState.LoadAssetBundle:
                return _op.progress * 0.5f;

            case LoaderState.LoadAsset:
                return 0.5f + _op.progress * 0.5f;
            }

            return 1;
        }

        public void Load()
        {
            switch (_state)
            {
            case LoaderState.Init:
                break;

            case LoaderState.Finish:
            {
                //热更完成后重新加载manifest这种
                manifest = null;
                if (null != bundle)
                {
                    bundle.Unload(true);
                    bundle = null;
                }
                break;
            }

            default:
                return;
            }

            _state = LoaderState.LoadAssetBundle;
            var path = ResPath.BuildExternalBundlePath(_bundleName);
            //Debug.Log($"ManifestLoader: manifest bundlePath: {path}");
            var request = AssetBundle.LoadFromFileAsync(path);
            _op = request;
            request.completed += OnComplete_Bundle;
        }

        void OnComplete_Bundle(AsyncOperation op)
        {
            _op = null;

            var bundleRequest = (AssetBundleCreateRequest)op;
            if (null == bundleRequest.assetBundle)
            {
                SetError(Err_Load_Bundle, $"manifest bundle load fail");
                Debug.LogError(ErrMsg);
                //manifest = null;
                SetFinishAndNotify(ErrMsg);
                return;
            }

            //Debug.Log($"manifest bundle load ok");
            bundle = bundleRequest.assetBundle;

            //加载资源
            _state = LoaderState.LoadAsset;
            var assetRequest = bundleRequest.assetBundle.LoadAssetAsync<AssetBundleManifest>("AssetBundleManifest");
            _op = assetRequest;
            assetRequest.completed += OnComplete_Asset;
        }

        void OnComplete_Asset(AsyncOperation op)
        {
            _op = null;

            var request = (AssetBundleRequest)op;
            if (null == request.asset)
            {
                SetError(Err_Load_Asset, $"manifest bundle load fail");
                Debug.LogError(ErrMsg);
                //manifest = null;
                SetFinishAndNotify(ErrMsg);
                return;
            }

            Debug.Log($"manifest asset load ok");
            manifest = (AssetBundleManifest) request.asset;
            SetError("", "");
            SetFinishAndNotify("");
        }

    } //end of class


}